
using System;
using System.Data;
using System.Linq;
using System.Linq.Dynamic;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

using Abp.UI;
using Abp.AutoMapper;
using Abp.Extensions;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Application.Services.Dto;
using Abp.Linq.Extensions;


using Yozeev.BusinessLogic;
using Yozeev.BusinessLogic.Dtos;
using Yozeev.BusinessLogic.DomainService;
using Yozeev.BusinessLogic.Authorization;
using Microsoft.AspNetCore.Mvc;
using Yozeev.Common;
using Abp.Domain.Entities.Auditing;

namespace Yozeev.BusinessLogic
{
	/// <summary>
	/// PriceAudit应用层服务的接口实现方法  
	///</summary>
	[AbpAuthorize]
	public class PriceAuditAppService : YozeevAppServiceBase, IPriceAuditAppService
    {
        private readonly IRepository<PriceAudit, Guid> _entityRepository;

		private readonly IRepository<Ticket, Guid> _ticketRepository;

		private readonly IRepository<TicketPrice, Guid> _ticketpriceRepository;

		private readonly IPriceAuditManager _entityManager;

		private readonly IQueryHelper _queryHelper;

		/// <summary>
		/// 构造函数 
		///</summary>
		public PriceAuditAppService(
        IRepository<PriceAudit, Guid> entityRepository
        ,IPriceAuditManager entityManager
		, IQueryHelper queryHelper
			, IRepository<Ticket, Guid> ticketRepository
			, IRepository<TicketPrice, Guid> ticketpriceRepository
		)
        {
            _entityRepository = entityRepository; 
             _entityManager=entityManager;
			_ticketRepository = ticketRepository;
			_queryHelper = queryHelper;
			_ticketpriceRepository = ticketpriceRepository;
        }


        /// <summary>
        /// 获取PriceAudit的分页列表信息——票总票价审核
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
		[HttpPost]
        public async Task<PagedResultDto<PriceAuditListDto>> GetPaged(GetPriceAuditsInput input)
		{ 
			var expression = _queryHelper.WhereExp<PriceAudit>(input.queryData);
			var query = from priceaudit in _entityRepository.GetAll().AsNoTracking()
                        .Where(expression)
						select new 
						{
                            priceaudit,
                            priceaudit.Ticket,
                            priceaudit.OrgTicketPrice
                        };
            // TODO:根据传入的参数添加过滤条件
            var list = new List<PriceAuditListDto>();
            query.ToList().ForEach(temp => {
                var _priceaudit = temp.priceaudit.MapTo<PriceAuditListDto>();
                _priceaudit.Ticket = temp.Ticket;
                if (temp.OrgTicketPrice != null)
                    _priceaudit.OrgTicketPrice = temp.OrgTicketPrice;
				_priceaudit.WarePositionName = L(_priceaudit.WarePosition.ToString());
				list.Add(_priceaudit);
            });
            // TODO:根据传入的参数添加过滤条件
            var count = list.Count();
			list = list.AsQueryable().OrderBy(input.Sorting)
					.PageBy(input)
					.ToList();

			// var entityListDtos = ObjectMapper.Map<List<PriceAuditListDto>>(entityList);
			//var entityListDtos = list.MapTo<List<PriceAuditListDto>>();

			return new PagedResultDto<PriceAuditListDto>(count, list);
		}


		/// <summary>
		/// 通过指定id获取PriceAuditListDto信息
		/// </summary>
		public async Task<PriceAuditListDto> GetById(EntityDto<Guid> input)
		{
			var entity = await _entityRepository.GetAsync(input.Id);

		    return entity.MapTo<PriceAuditListDto>();
		}

		/// <summary>
		/// 获取编辑 PriceAudit
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task<GetPriceAuditForEditOutput> GetForEdit(NullableIdDto<Guid> input)
		{
			var output = new GetPriceAuditForEditOutput();
PriceAuditEditDto editDto;

			if (input.Id.HasValue)
			{
				var entity = await _entityRepository.GetAsync(input.Id.Value);

				editDto = entity.MapTo<PriceAuditEditDto>();

				//priceAuditEditDto = ObjectMapper.Map<List<priceAuditEditDto>>(entity);
			}
			else
			{
				editDto = new PriceAuditEditDto();
			}

			output.PriceAudit = editDto;
			return output;
		}


		/// <summary>
		/// 添加或者修改PriceAudit的公共方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task CreateOrUpdate(CreateOrUpdatePriceAuditInput input)
		{

            input.PriceAudit.SetTime();
            if (input.PriceAudit.Id.HasValue)
			{
				await Update(input.PriceAudit);
			}
			else
			{
				await Create(input.PriceAudit);
			}
		}


		/// <summary>
		/// 新增PriceAudit
		/// </summary>
		protected virtual async Task<PriceAuditEditDto> Create(PriceAuditEditDto input)
		{
			//TODO:新增前的逻辑判断，是否允许新增

            // var entity = ObjectMapper.Map <PriceAudit>(input);
            var entity=input.MapTo<PriceAudit>();
			

			entity = await _entityRepository.InsertAsync(entity);
			return entity.MapTo<PriceAuditEditDto>();
		}

		/// <summary>
		/// 编辑PriceAudit
		/// </summary>
		protected virtual async Task Update(PriceAuditEditDto input)
		{
			//TODO:更新前的逻辑判断，是否允许更新

			var entity = await _entityRepository.GetAsync(input.Id.Value);

            if (entity.AuditStatus == AuditStatusEnum.ThroughAudit) return;
            input.MapTo(entity);
            entity.AuditStatus = AuditStatusEnum.WaiteAudit;
			// ObjectMapper.Map(input, entity);
		    await _entityRepository.UpdateAsync(entity);
		}



		/// <summary>
		/// 删除PriceAudit信息的方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task Delete(EntityDto<Guid> input)
		{
			//TODO:删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(input.Id);
		}



		/// <summary>
		/// 批量删除PriceAudit的方法
		/// </summary>
		public async Task BatchDelete(List<Guid> input)
		{
			// TODO:批量删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(s => input.Contains(s.Id));
		}


		/// <summary>
		/// 导出PriceAudit为excel表,等待开发。
		/// </summary>
		/// <returns></returns>
		//public async Task<FileDto> GetToExcel()
		//{
		//	var users = await UserManager.Users.ToListAsync();
		//	var userListDtos = ObjectMapper.Map<List<UserListDto>>(users);
		//	await FillRoleNames(userListDtos);
		//	return _userListExcelExporter.ExportToFile(userListDtos);
		//}


		/// <summary>
		/// 审核成功
		///</summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task UpdateThroughAudit(PriceAuditEditDto input)
		{
			////新增价格审核数据
			//var priceaudit = input.MapTo<PriceAudit>();
			//priceaudit = await _entityRepository.InsertAsync(priceaudit);
			//var price = _ticketpriceRepository.GetAll().Where(x=>x.Id==priceaudit.OrgTicketPriceId);

			//将审核状态改为审核通过
			var entity = await _entityRepository.GetAsync((Guid)input.Id);
            if (entity.AuditStatus == AuditStatusEnum.ThroughAudit) return;
			entity.AuditStatus = AuditStatusEnum.ThroughAudit;
			await _entityRepository.UpdateAsync(entity);
			if (input.OrgTicketPriceId != null)
            {
                var p = _ticketpriceRepository.Get((Guid)entity.OrgTicketPriceId);
                p.IsEnabled = input.IsEnabled;
				await _ticketpriceRepository.UpdateAsync(p);
			}
			else {
				var p = new TicketPrice() {
                    TicketId = entity.TicketId,
                    Price = entity.Price,
                    Discount = entity.Discount,
                    RDiscount = entity.RDiscount,
                    UpperTime = entity.UpperTime,
                    Position = PositionEnum.windows,
                    IsEnabled = entity.IsEnabled,
                    CreationTime = DateTime.Now,
                    CreatorUserId = AbpSession.UserId,
					TicketName = entity.TicketName,
					WarePosition = entity.WarePosition,
				};
                if (entity.LowerTime != null)
                    p.LowerTime = (DateTime)entity.LowerTime;
				await _ticketpriceRepository.InsertAsync(p);
			}
		}

		/// <summary>
		/// 驳回重改
		///</summary>
		/// <param name="input"></param>
		/// <returns></returns> 
		public async Task UpdateRejecteAudit(PriceAuditEditDto input)
		{
			var entity = await _entityRepository.GetAsync((Guid)input.Id);
			if (entity.AuditStatus != AuditStatusEnum.ThroughAudit)
			{
				entity.AuditStatus = AuditStatusEnum.RejecteAudit;
			}
			await _entityRepository.UpdateAsync(entity);
		}
	}
}


